<template>
  <view class="wk-select-list list">
    <view
      v-for="item in optionsList"
      :key="item.index"
      :class="{active: item.checked}"
      class="list-item"
      @click="handleSelected(item.index)">
      <view class="list-item_icon">
        <image :src="$static('images/icon/check.png')" class="checked-icon" />
      </view>
      <view v-if="hasSlot" class="list-item_label">
        <slot :scope-data="item.data" />
      </view>
      <text v-else class="list-item_label">
        {{ item.data[labelField] }}
      </text>
    </view>
  </view>
</template>

<script>
	/**
	 * 选项选择
	 * @property {Array<Object>} list 选项列表
	 * @property {Array} defaultVal 默认勾选的项
	 * @property {String} labelField 选项中展示的字段
	 * @property {String} valueField 选项值字段
	 * @property {Number} max 最大能选择几项，默认正无穷
	 * @property {Number} min 至少选择几项，默认0
	 * @event {Function} change 勾选项发生变化
	 * @slots 自定义选项样式
	 */
  import { isObject } from '@/utils/types.js'

  export default {
    name: 'WkSelectList',
    props: {
      value: {
        type: Array,
        default: () => []
      },
      list: {
        type: Array,
        required: true
      },
      labelField: {
        type: String,
        default: 'label'
      },
      valueField: {
        type: String,
        default: 'value'
      },
      max: {
        type: Number,
        default: 1 / 0
      },
      min: {
        type: Number,
        default: 0
      }
    },
    data() {
      return {
        maxlength: 0,
        optionsList: [], // 选项数组
        lastIndex: null // 记录最后一次选中的是第几项
      }
    },
    computed: {
      hasSlot() {
        return this.$scopedSlots.default
      }
    },
    watch: {
      list: {
        handler(val) {
          this.optionsList = this.list.map((item, index) => {
            return {
              data: item,
              checked: false,
              index: index
            }
          })
          this.getCheckedList()
        },
        immediate: true,
        deep: true
      },
      value: {
        handler() {
          this.getCheckedList()
        },
        deep: true
      },
      max: {
        handler(val) {
          if (this.$isEmpty(val) || val === 0) {
            this.maxlength = 1 / 0
          } else {
            this.maxlength = val
          }
        },
        immediate: true,
        deep: true
      }
    },
    methods: {
      /**
       * 勾选默认选中的项
       */
      getCheckedList() {
        const that = this
        this.optionsList.forEach((item, index) => {
          const findIndex = this.value.findIndex(val => {
            if (isObject(val)) {
              return item.data[that.valueField] === val[that.valueField]
            } else {
              return item.data[that.valueField] === val
            }
          })
          if (findIndex !== -1) {
            if (that.lastIndex === null) {
              that.lastIndex = index
            }
            item.checked = true
          } else {
            item.checked = false
          }
          that.$set(item, 'checked', item.checked)
        })
      },

      /**
       * 选中
       * @param {Number} index
       */
      handleSelected(index) {
        const item = this.optionsList[index]
        item.checked = !item.checked

        // 判断已经选择的项是否超出最大选择数量，如果超出则把最后一次选中项的置为未选中
        const checkedLen = this.optionsList.filter(o => o.checked).length
        if (
          index !== this.lastIndex &&
          this.lastIndex !== null &&
          (checkedLen > this.maxlength)
        ) {
          const lastItem = this.optionsList[this.lastIndex]
          lastItem.checked = false
          this.$set(this.optionsList, this.lastIndex, lastItem)
        }

        if (item.checked) {
          this.lastIndex = index
        }

        this.$set(this.optionsList, index, item)
        this.emitSelected()
      },

      emitSelected() {
        const filterRes = this.optionsList.filter(o => o.checked)
        const res = filterRes.map(o => o.data)
        this.$emit('input', res)
        this.$emit('change', res)
      }
    }
  }
</script>

<style scoped lang="scss">
	.wk-select-list {
		.list-item {
			padding: 0 30rpx;
			background-color: white;
			@include left;
			.list-item_icon {
				width: 38rpx;
				height: 38rpx;
				border: 1rpx solid #ccc;
				border-radius: 50%;
				margin-right: 22rpx;
				@include center;
				.checked-icon {
					width: 23rpx;
					height: 23rpx;
				}
			}
			.list-item_label {
				flex: 1;
				font-size: 30rpx;
				color: $dark;
				border-bottom: 1rpx solid $border-color;
				padding: 24rpx 0;
			}

			&.active {
				.list-item_icon {
					background-color: $theme-color;
					border-color: $theme-color;
				}
			}
		}
	}
</style>
